home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / bionicc.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  7KB  |  280 lines

  1. /***************************************************************************
  2.  
  3.   Bionic Commando Video Hardware
  4.  
  5. ***************************************************************************/
  6.  
  7. #include "driver.h"
  8. #include "vidhrdw/generic.h"
  9.  
  10. unsigned char *bionicc_fgvideoram;
  11. unsigned char *bionicc_bgvideoram;
  12. unsigned char *bionicc_txvideoram;
  13.  
  14. static struct tilemap *tx_tilemap, *bg_tilemap, *fg_tilemap;
  15. static int flipscreen;
  16.  
  17.  
  18. /***************************************************************************
  19.  
  20.   Callbacks for the TileMap code
  21.  
  22. ***************************************************************************/
  23.  
  24. static void get_bg_tile_info(int tile_index)
  25. {
  26.     UINT16 *videoram1 = (UINT16 *)bionicc_bgvideoram;
  27.     int attr = videoram1[2*tile_index+1];
  28.     SET_TILE_INFO(1,(videoram1[2*tile_index] & 0xff) + ((attr & 0x07) << 8),(attr & 0x18) >> 3);
  29.     tile_info.flags = TILE_FLIPXY((attr & 0xc0) >> 6);
  30. }
  31.  
  32. static void get_fg_tile_info(int tile_index)
  33. {
  34.     UINT16 *videoram1 = (UINT16 *)bionicc_fgvideoram;
  35.     int attr = videoram1[2*tile_index+1];
  36.     SET_TILE_INFO(2,(videoram1[2*tile_index] & 0xff) + ((attr & 0x07) << 8),(attr & 0x18) >> 3);
  37.     if ((attr & 0xc0) == 0xc0)
  38.     {
  39.         tile_info.priority = 2;
  40.         tile_info.flags = 0;
  41.     }
  42.     else
  43.     {
  44.         tile_info.priority = (attr & 0x20) >> 5;
  45.         tile_info.flags = TILE_FLIPXY((attr & 0xc0) >> 6);
  46.     }
  47. }
  48.  
  49. static void get_tx_tile_info(int tile_index)
  50. {
  51.     UINT16 *videoram1 = (UINT16 *)bionicc_txvideoram;
  52.     int attr = videoram1[tile_index + 0x400];
  53.     SET_TILE_INFO(0,(videoram1[tile_index] & 0xff) + ((attr & 0x00c0) << 2),attr & 0x3f);
  54. }
  55.  
  56.  
  57.  
  58. /***************************************************************************
  59.  
  60.   Start the video hardware emulation.
  61.  
  62. ***************************************************************************/
  63.  
  64. int bionicc_vh_start(void)
  65. {
  66.     tx_tilemap = tilemap_create(get_tx_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,  8,8,32,32);
  67.     fg_tilemap = tilemap_create(get_fg_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,64,64);
  68.     bg_tilemap = tilemap_create(get_bg_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,  8,8,64,64);
  69.  
  70.     if (!fg_tilemap || !bg_tilemap || !tx_tilemap)
  71.         return 1;
  72.  
  73.     tx_tilemap->transparent_pen = 3;
  74.     fg_tilemap->transparent_pen = 15;
  75.     bg_tilemap->transparent_pen = 15;
  76.  
  77.     return 0;
  78. }
  79.  
  80.  
  81.  
  82. /***************************************************************************
  83.  
  84.   Memory handlers
  85.  
  86. ***************************************************************************/
  87.  
  88. WRITE_HANDLER( bionicc_bgvideoram_w )
  89. {
  90.     int oldword = READ_WORD(&bionicc_bgvideoram[offset]);
  91.     int newword = COMBINE_WORD(oldword,data);
  92.  
  93.     if (oldword != newword)
  94.     {
  95.         int tile_index = offset/4;
  96.         WRITE_WORD(&bionicc_bgvideoram[offset],newword);
  97.         tilemap_mark_tile_dirty(bg_tilemap,tile_index);
  98.     }
  99. }
  100.  
  101. WRITE_HANDLER( bionicc_fgvideoram_w )
  102. {
  103.     int oldword = READ_WORD(&bionicc_fgvideoram[offset]);
  104.     int newword = COMBINE_WORD(oldword,data);
  105.  
  106.     if (oldword != newword)
  107.     {
  108.         int tile_index = offset/4;
  109.         WRITE_WORD(&bionicc_fgvideoram[offset],newword);
  110.         tilemap_mark_tile_dirty(fg_tilemap,tile_index);
  111.     }
  112. }
  113.  
  114. WRITE_HANDLER( bionicc_txvideoram_w )
  115. {
  116.     int oldword = READ_WORD(&bionicc_txvideoram[offset]);
  117.     int newword = COMBINE_WORD(oldword,data);
  118.  
  119.     if (oldword != newword)
  120.     {
  121.         int tile_index = (offset&0x7ff)/2;
  122.         WRITE_WORD(&bionicc_txvideoram[offset],newword);
  123.         tilemap_mark_tile_dirty(tx_tilemap,tile_index);
  124.     }
  125. }
  126.  
  127. READ_HANDLER( bionicc_bgvideoram_r )
  128. {
  129.     return READ_WORD(&bionicc_bgvideoram[offset]);
  130. }
  131.  
  132. READ_HANDLER( bionicc_fgvideoram_r )
  133. {
  134.     return READ_WORD(&bionicc_fgvideoram[offset]);
  135. }
  136.  
  137. READ_HANDLER( bionicc_txvideoram_r )
  138. {
  139.     return READ_WORD(&bionicc_txvideoram[offset]);
  140. }
  141.  
  142. WRITE_HANDLER( bionicc_paletteram_w )
  143. {
  144.     paletteram_RRRRGGGGBBBBIIII_word_w(offset,(data & 0xfff1) | ((data & 0x0007) << 1));
  145. }
  146.  
  147. WRITE_HANDLER( bionicc_scroll_w )
  148. {
  149.     switch( offset )
  150.     {
  151.         case 0:
  152.             tilemap_set_scrollx(fg_tilemap,0,data);
  153.             break;
  154.         case 2:
  155.             tilemap_set_scrolly(fg_tilemap,0,data);
  156.             break;
  157.         case 4:
  158.             tilemap_set_scrollx(bg_tilemap,0,data);
  159.             break;
  160.         case 6:
  161.             tilemap_set_scrolly(bg_tilemap,0,data);
  162.             break;
  163.     }
  164. }
  165.  
  166. WRITE_HANDLER( bionicc_gfxctrl_w )
  167. {
  168.     data >>= 8;
  169.  
  170.     flipscreen = data & 1;
  171.     tilemap_set_flip(ALL_TILEMAPS,flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
  172.  
  173.     tilemap_set_enable(bg_tilemap,data & 0x20);    /* guess */
  174.     tilemap_set_enable(fg_tilemap,data & 0x10);    /* guess */
  175.  
  176.     coin_counter_w(0,data & 0x80);
  177.     coin_counter_w(1,data & 0x40);
  178. }
  179.  
  180.  
  181.  
  182. /***************************************************************************
  183.  
  184.   Display refresh
  185.  
  186. ***************************************************************************/
  187.  
  188. static void bionicc_draw_sprites( struct osd_bitmap *bitmap )
  189. {
  190.     int offs;
  191.     const struct GfxElement *gfx = Machine->gfx[3];
  192.     const struct rectangle *clip = &Machine->drv->visible_area;
  193.  
  194.     for (offs = spriteram_size-8;offs >= 0;offs -= 8)
  195.     {
  196.         int tile_number = READ_WORD(&buffered_spriteram[offs])&0x7ff;
  197.         if( tile_number!=0x7FF ){
  198.             int attr = READ_WORD(&buffered_spriteram[offs+2]);
  199.             int color = (attr&0x3C)>>2;
  200.             int flipx = attr&0x02;
  201.             int flipy = 0;
  202.             int sx= (signed short)READ_WORD(&buffered_spriteram[offs+6]);
  203.             int sy= (signed short)READ_WORD(&buffered_spriteram[offs+4]);
  204.             if(sy>512-16) sy-=512;
  205.             if (flipscreen)
  206.             {
  207.                 sx = 240 - sx;
  208.                 sy = 240 - sy;
  209.                 flipx = !flipx;
  210.                 flipy = !flipy;
  211.             }
  212.  
  213.             drawgfx( bitmap, gfx,
  214.                 tile_number,
  215.                 color,
  216.                 flipx,flipy,
  217.                 sx,sy,
  218.                 clip,TRANSPARENCY_PEN,15);
  219.         }
  220.     }
  221. }
  222.  
  223. void mark_sprite_colors( void )
  224. {
  225.     int offs, code, color, i, pal_base;
  226.     int colmask[16];
  227.  
  228.     pal_base = Machine->drv->gfxdecodeinfo[3].color_codes_start;
  229.     for(i=0;i<16;i++) colmask[i] = 0;
  230.  
  231.     for (offs = 0; offs < 0x500;offs += 8)
  232.     {
  233.  
  234.         code = READ_WORD(&buffered_spriteram[offs]) & 0x7ff;
  235.         if( code != 0x7FF ) {
  236.             color = (READ_WORD(&buffered_spriteram[offs+2]) & 0x3c) >> 2;
  237.             colmask[color] |= Machine->gfx[3]->pen_usage[code];
  238.         }
  239.     }
  240.  
  241.     for (color = 0;color < 16;color++)
  242.     {
  243.         for (i = 0;i < 15;i++)
  244.         {
  245.             if (colmask[color] & (1 << i))
  246.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  247.         }
  248.     }
  249. }
  250.  
  251. void bionicc_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  252. {
  253.     tilemap_update(ALL_TILEMAPS);
  254.  
  255.     palette_init_used_colors();
  256.     mark_sprite_colors();
  257.     palette_used_colors[0] |= PALETTE_COLOR_VISIBLE;
  258.  
  259.     if (palette_recalc())
  260.         tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  261.  
  262.     tilemap_render(ALL_TILEMAPS);
  263.  
  264.     fillbitmap(bitmap,Machine->pens[0],&Machine->drv->visible_area);
  265.     tilemap_draw(bitmap,fg_tilemap,2);
  266.     tilemap_draw(bitmap,bg_tilemap,0);
  267.     tilemap_draw(bitmap,fg_tilemap,0);
  268.     bionicc_draw_sprites(bitmap);
  269.     tilemap_draw(bitmap,fg_tilemap,1);
  270.     tilemap_draw(bitmap,tx_tilemap,0);
  271. }
  272.  
  273. void bionicc_eof_callback(void)
  274. {
  275.     /* Mish: Spriteram is always 1 frame ahead, suggesting buffering.  I can't
  276.         find a register to control this so I assume it happens automatically
  277.         every frame at the end of vblank */
  278.     buffer_spriteram_w(0,0);
  279. }
  280.